package cn.iocoder.yudao.module.wms.service.vendorclassify;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.wms.controller.admin.vendorclassify.vo.VendorClassifyPageReqVO;
import cn.iocoder.yudao.module.wms.controller.admin.vendorclassify.vo.VendorClassifySaveReqVO;
import cn.iocoder.yudao.module.wms.dal.dataobject.vendor.VendorDO;
import cn.iocoder.yudao.module.wms.dal.dataobject.vendorclassify.VendorClassifyDO;
import cn.iocoder.yudao.module.wms.dal.mysql.vendor.VendorMapper;
import cn.iocoder.yudao.module.wms.dal.mysql.vendorclassify.VendorClassifyMapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.*;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.*;

/**
 * 供应商分类 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class VendorClassifyServiceImpl implements VendorClassifyService {

    @Resource
    private VendorClassifyMapper vendorClassifyMapper;

    @Resource
    private VendorMapper vendorMapper;

    @Override
    public Long createVendorClassify(VendorClassifySaveReqVO createReqVO) {
        validateCodeOrNameExists(createReqVO);
        // 插入
        VendorClassifyDO vendorClassify = BeanUtils.toBean(createReqVO, VendorClassifyDO.class);
        vendorClassifyMapper.insert(vendorClassify);
        // 返回
        return vendorClassify.getId();
    }

    @Override
    public void updateVendorClassify(VendorClassifySaveReqVO updateReqVO) {
        // 校验存在
        validateVendorClassifyExists(updateReqVO.getId());
        validateCodeOrNameExists(updateReqVO);
        // 更新
        VendorClassifyDO updateObj = BeanUtils.toBean(updateReqVO, VendorClassifyDO.class);
        vendorClassifyMapper.updateById(updateObj);
    }

    @Override
    public void deleteVendorClassify(Long id) {
        // 校验存在
        validateVendorClassifyExists(id);
        // 校验是否有子分类
        if (vendorClassifyMapper.selectCount(VendorClassifyDO::getParentId, id) > 0) {
            throw exception(VENDOR_CLASSIFY_EXITS_CHILDREN);
        }
        // 校验分类下是否有供应商
        if (vendorMapper.selectCount(VendorDO::getClassifyId, id) > 0) {
            throw exception(VENDOR_CLASSIFY_EXITS_VENDOR);
        }
        // 删除
        vendorClassifyMapper.deleteById(id);
    }

    /**
     * 校验供应商分类是否存在
     * @param id 供应商分类id
     */
    private void validateVendorClassifyExists(Long id) {
        if (vendorClassifyMapper.selectById(id) == null) {
            throw exception(VENDOR_CLASSIFY_NOT_EXISTS);
        }
    }

    /**
     * 校验编码或名称是否存在
     * @param reqVO 供应商分类Request VO
     */
    private void validateCodeOrNameExists(VendorClassifySaveReqVO reqVO) {
        if (vendorClassifyMapper.selectCount(VendorClassifyDO::getCode, reqVO.getCode()) > 0) {
            throw exception(VENDOR_CLASSIFY_CODE_EXISTS);
        }
        if (vendorClassifyMapper.selectCount(VendorClassifyDO::getName, reqVO.getName()) > 0) {
            throw exception(VENDOR_CLASSIFY_NAME_EXISTS);
        }
    }

    @Override
    public VendorClassifyDO getVendorClassify(Long id) {
        return vendorClassifyMapper.selectById(id);
    }

    @Override
    public PageResult<VendorClassifyDO> getVendorClassifyPage(VendorClassifyPageReqVO pageReqVO) {
        return vendorClassifyMapper.selectPage(pageReqVO, getClassifyCondition(pageReqVO.getParentId()));
    }

    @Override
    public List<VendorClassifyDO> getVendorClassifyList() {
        return vendorClassifyMapper.selectList();
    }

    @Override
    public List<VendorClassifyDO> getChildVendorClassifyList(Collection<Long> ids) {
        List<VendorClassifyDO> children = new LinkedList<>();
        // 遍历每一层
        Collection<Long> parentIds = ids;
        for (int i = 0; i < Short.MAX_VALUE; i++) {
            List<VendorClassifyDO> classifys = vendorClassifyMapper.selectList(VendorClassifyDO::getParentId, parentIds);
            if (CollUtil.isEmpty(classifys)) {
                break;
            }
            children.addAll(classifys);
            parentIds = convertSet(classifys, VendorClassifyDO::getId);
        }
        return children;
    }

    /**
     * 获得存货分类条件：查询指定存货分类的子分类编号们，包括自身
     *
     * @param classifyId 存货分类编号
     * @return 存货分类编号集合
     */
    private Set<Long> getClassifyCondition(Long classifyId) {
        if (classifyId == null) {
            return Collections.emptySet();
        }
        Set<Long> classifyIds = convertSet(getChildVendorClassifyList(Collections.singleton(classifyId)), VendorClassifyDO::getId);
        classifyIds.add(classifyId); // 包括自身
        return classifyIds;
    }

}